﻿// Decompiled with JetBrains decompiler
// Type: MCM.Implementation.JsonSettingsPreset
// Assembly: MCMv5, Version=5.10.2.0, Culture=neutral, PublicKeyToken=null
// MVID: 7AB326B9-B2B4-41C2-9177-68E944071101
// Assembly location: D:\steam\steamapps\workshop\content\261550\2859238197\bin\Win64_Shipping_Client\MCMv5.dll

using BUTR.DependencyInjection;
using BUTR.DependencyInjection.Logger;
using MCM.Abstractions;
using MCM.Abstractions.Base;
using MCM.Abstractions.GameFeatures;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Text;

#nullable enable
namespace MCM.Implementation
{
  public sealed class JsonSettingsPreset : ISettingsPreset
  {
    private readonly GameFile _file;
    private readonly Func<BaseSettings> _getNewSettings;
    private readonly JsonSerializerSettings _jsonSerializerSettings;
    private readonly object _lock = new object();
    private readonly Dictionary<string, object?> _existingObjects = new Dictionary<string, object>();

    public static string? GetPresetId(string content)
    {
      try
      {
        return JsonConvert.DeserializeObject<JsonSettingsPreset.PresetContainerDefinition>(content)?.Id;
      }
      catch (Exception ex)
      {
        return (string) null;
      }
    }

    public static JsonSettingsPreset? FromFile(BaseSettings settings, GameFile file)
    {
      return JsonSettingsPreset.FromFile(settings.Id, file, new Func<BaseSettings>(settings.CreateNew));
    }

    public static JsonSettingsPreset? FromFile(
      string settingsId,
      GameFile file,
      Func<BaseSettings> getNewSettings)
    {
      IFileSystemProvider service = GenericServiceProvider.GetService<IFileSystemProvider>();
      if (service == null)
        return (JsonSettingsPreset) null;
      byte[] bytes = service.ReadData(file);
      if (bytes == null)
        return (JsonSettingsPreset) null;
      JsonSettingsPreset.PresetContainerDefinition containerDefinition = JsonConvert.DeserializeObject<JsonSettingsPreset.PresetContainerDefinition>(Encoding.UTF8.GetString(bytes));
      return containerDefinition == null ? (JsonSettingsPreset) null : new JsonSettingsPreset(settingsId, containerDefinition.Id, containerDefinition.Name, file, getNewSettings);
    }

    public string SettingsId { get; }

    public string Id { get; }

    public string Name { get; }

    public JsonSettingsPreset(BaseSettings settings, string id, string name, GameFile file)
      : this(settings.Id, id, name, file, new Func<BaseSettings>(settings.CreateNew))
    {
    }

    public JsonSettingsPreset(
      string settingsId,
      string id,
      string name,
      GameFile file,
      Func<BaseSettings> getNewSettings)
    {
      this.SettingsId = settingsId;
      this.Id = id;
      this.Name = name;
      this._file = file;
      this._getNewSettings = getNewSettings;
      IBUTRLogger<JsonSettingsPreset> logger = GenericServiceProvider.GetService<IBUTRLogger<JsonSettingsPreset>>() ?? (IBUTRLogger<JsonSettingsPreset>) new DefaultBUTRLogger<JsonSettingsPreset>();
      JsonSerializerSettings serializerSettings = new JsonSerializerSettings();
      serializerSettings.Formatting = Formatting.Indented;
      serializerSettings.Converters.Add((JsonConverter) new BaseSettingsJsonConverter((IBUTRLogger) logger, new Action<string, object>(this.AddSerializationProperty), new Action(this.ClearSerializationProperties)));
      serializerSettings.Converters.Add((JsonConverter) new DropdownJsonConverter((IBUTRLogger) logger, new Func<string, object>(this.GetSerializationProperty)));
      this._jsonSerializerSettings = serializerSettings;
    }

    public BaseSettings LoadPreset()
    {
      BaseSettings settings = this._getNewSettings();
      IFileSystemProvider service = GenericServiceProvider.GetService<IFileSystemProvider>();
      if (service == null)
        return settings;
      byte[] bytes = service.ReadData(this._file);
      if (bytes == null)
      {
        this.SavePreset(settings);
        return settings;
      }
      string str = Encoding.UTF8.GetString(bytes);
      lock (this._lock)
      {
        try
        {
          JsonSettingsPreset.PresetContainer presetContainer = new JsonSettingsPreset.PresetContainer();
          presetContainer.Id = this.Id;
          presetContainer.Name = this.Name;
          presetContainer.Settings = settings;
          JsonSettingsPreset.PresetContainer target = presetContainer;
          JsonConvert.PopulateObject(str, (object) target, this._jsonSerializerSettings);
        }
        catch (Exception ex)
        {
        }
      }
      return settings;
    }

    public bool SavePreset(BaseSettings settings)
    {
      IFileSystemProvider service = GenericServiceProvider.GetService<IFileSystemProvider>();
      if (service == null)
        return false;
      try
      {
        JsonSettingsPreset.PresetContainer presetContainer = new JsonSettingsPreset.PresetContainer();
        presetContainer.Id = this.Id;
        presetContainer.Name = this.Name;
        presetContainer.Settings = settings;
        string s = JsonConvert.SerializeObject((object) presetContainer, this._jsonSerializerSettings);
        service.WriteData(this._file, Encoding.UTF8.GetBytes(s));
        return true;
      }
      catch (Exception ex)
      {
        return false;
      }
    }

    private object? GetSerializationProperty(string path)
    {
      lock (this._lock)
      {
        object obj;
        return this._existingObjects.TryGetValue(path, out obj) ? obj : (object) null;
      }
    }

    private void AddSerializationProperty(string path, object? value)
    {
      this._existingObjects.Add(path, value);
    }

    private void ClearSerializationProperties() => this._existingObjects.Clear();

    private class PresetContainerDefinition
    {
      [JsonProperty(Order = 1)]
      public string Id { get; set; } = string.Empty;

      [JsonProperty(Order = 2)]
      public string Name { get; set; } = string.Empty;
    }

    private sealed class PresetContainer : JsonSettingsPreset.PresetContainerDefinition
    {
      [JsonProperty(Order = 3)]
      public BaseSettings? Settings { get; set; }
    }
  }
}
